/**
 * Created by asus on 2017/5/12.
 */
import java.util.Scanner;
import java.util.StringTokenizer;
import java.util.Stack;
import java.util.*;
public class Method {
    private final char ADD = '+',SUBTRACT = '-';
    private final char MULTIPLY = '*',DIVIDE = '/';
    private final char LEFT = '(',RIGHT = ')';
    private Stack<String> stack  = new Stack<>();;
    private Stack<String> Opera = new Stack<>();
    private StringBuilder Methoder = new StringBuilder();

    public String evaluate(String expr){
        int op1,op2,result = 0;
        String token;
        Scanner tokenizer = new Scanner(expr);
        while (tokenizer.hasNext()) {
            token = tokenizer.next();
            if (isOperator(token)) {

                if (Opera.empty()) {
                    Opera.push(token);
                } else
                    //如果读入的操作符为非")"且优先级比栈顶元素的优先级高或一样，则将操作符压入栈
                    {
                    if (Number(Opera.peek()) < Number(token) && !token.equals(")")) {
                        Opera.push(token);
                    } else if (Number(Opera.peek()) > Number(token) && !token.equals(")")) {
                        while (Opera.size() != 0 && Number(Opera.peek()) >= Number(token) && !Opera.peek().equals("(")) {
                            if (!Opera.peek().equals("(")) {
                                String operator = Opera.pop();
                                Methoder.append(operator);
                                stack.push(operator);
                            }
                        }
                        Opera.push(token);
                    }
                    //如果读入的操作符是")"，则弹出从栈顶开始第一个"("及其之前的所有操作符
                    else if (token.equals(")")) {
                        while (!Opera.peek().equals("(")) {
                            String operator = Opera.pop();
                            Methoder.append(operator);
                            stack.push(operator);
                        }
                        Opera.pop();
                    }
                }
            } else {
                Methoder.append(token);
                stack.push(token);
            }
        }
        if (!Opera.isEmpty()) {
            Iterator<String> iterator=Opera.iterator();
            while (iterator.hasNext()) {
                String operator=iterator.next();
                Methoder.append(operator);
                stack.push(operator);
                iterator.remove();
            }
        }


         return String.valueOf(Methoder);



    }

    private int evalSingleOp (char operation , int op1,int op2){
        int result = 0;
        switch (operation){
            case ADD:
                result = op1+op2;
                break;
            case SUBTRACT:
                result = op1-op2;
                break;
            case MULTIPLY:
                result = op1*op2;
                break;
            case DIVIDE:
                result = op1/op2;
        }
        return result;
    }

    private boolean isOperator (String token){
        return (token.equals("+") || token.equals("-") || token.equals("*")|| token.equals("/")||token.equals("(")||token.equals(")"));
    }
    private static int Number(String token){
        switch (token) {
            case "+":return 1;
            case "-":return 1;
            case "*":return 2;
            case "/":return 2;
            case "(":return 3;
            case ")":return 3;
            default :return 0;
        }
    }
}
